/*
 *******************
 ******************************* C SOURCE FILE *******************************
 ** 							 *******************						   **
 ** 																		   **
 ** project : ClockSync 											           **
 ** filename :Timer															   **
 ** version : 1 															   **
 ** date : -	2012.04.10.													   **
 ** 																		   **
 *****************************************************************************
 ** 																		   **
 ** Copyright (c) 2012,		   							  				       **
 ** All rights reserved.													   **
 ** 																		   **
 *****************************************************************************
 VERSION HISTORY:
 ----------------
 Version : 1
 Date : -
 Revised by : -
 Description : Original version.
 */
#define _TIMER_C_SRC
/****************************************************************************/
/** 																	   **/
/** 							MODULES USED 							   **/
/** 																	   **/
/****************************************************************************/

#include <cyg/hal/hal_io.h>

#include <com_r04_s01b.h>
#include "platform.h"

#include "UserTasks.h"
#include "Timer.h"
/****************************************************************************/
/** 																	   **/
/** 							DEFINITIONS AND MACROS 					   **/
/** 																	   **/
/****************************************************************************/

/****************************************************************************/
/** 																	   **/
/** 							TYPEDEFS AND STRUCTURES 				   **/
/** 																	   **/
/****************************************************************************/

/****************************************************************************/
/** 																	   **/
/** 							PROTOTYPES OF LOCAL FUNCTIONS			   **/
/** 																	   **/
/****************************************************************************/

/****************************************************************************/
/** 																	   **/
/** 							EXPORTED VARIABLES						   **/
/** 																	   **/
/****************************************************************************/

cyg_interrupt timer1_int;
cyg_handle_t timer1_int_handle;

/****************************************************************************/
/** 																	   **/
/** 							GLOBAL VARIABLES 						   **/
/** 																	   **/
/****************************************************************************/
static bool led_val;
static volatile cyg_uint32 InterruptBit;

/****************************************************************************/
/** 																	   **/
/** 							EXPORTED FUNCTIONS 						   **/
/** 																	   **/
/****************************************************************************/
cyg_uint32 Get_time(void)
{
	cyg_uint32 time;
	HAL_READ_UINT32(TIMER1_TC, time);

	return time;
}
void Set_time(cyg_uint32 new_time)
{
	HAL_WRITE_UINT32(TIMER1_TC, new_time);
}

void Update_request_timer(cyg_uint32 time_to_add)
{
	cyg_uint32 curr_mr;

	HAL_READ_UINT32(TIMER1_MR0, curr_mr);
	HAL_WRITE_UINT32(TIMER1_MR0, curr_mr + time_to_add);
	diag_printf("request updated ... writed : %u  %u \r\n", curr_mr, curr_mr + time_to_add);

}

void Update_answer_timer(cyg_uint32 time_to_add)
{
	cyg_uint32 curr_mr;

	HAL_READ_UINT32(TIMER1_MR1, curr_mr);
	HAL_WRITE_UINT32(TIMER1_MR1, curr_mr + time_to_add);

diag_printf("answer updated ... writed : %u  %u \r\n", curr_mr, curr_mr + time_to_add);
}
void Set_answer_timer(cyg_uint32 time_to_set)
{
	cyg_uint32 curr_time;
	cyg_uint32 old_MCR;

	/* set the new value */
	HAL_READ_UINT32(TIMER1_TC, curr_time);
	HAL_WRITE_UINT32(TIMER1_MR1, curr_time + time_to_set);

	/* enable match register */
	HAL_READ_UINT32(TIMER1_MCR, old_MCR);
	HAL_WRITE_UINT32(TIMER1_MCR, old_MCR | 0x8);

	diag_printf("answer writed : %u  %u \r\n", curr_time, curr_time
			+ time_to_set);

}
void Set_request_timer(cyg_uint32 time_to_set)
{
	cyg_uint32 curr_time;
	cyg_uint32 old_MCR;

	/* set the new match value */
	HAL_READ_UINT32(TIMER1_TC, curr_time);
	HAL_WRITE_UINT32(TIMER1_MR0, curr_time + time_to_set);

	/* enable match register */
	HAL_READ_UINT32(TIMER1_MCR, old_MCR);
	HAL_WRITE_UINT32(TIMER1_MCR, old_MCR | (0x1));

	diag_printf("request writed : %u  %u \r\n", curr_time, curr_time
			+ time_to_set);

}

void Timer1_init()
{
	/* Disable the Timer1 module */
	HAL_WRITE_UINT32(TIMER1_TCR, 0x2);

	/* setup the first request time*/

	/*
	 *  wait one period and if there is no request: request clocks
	 * if there is request it will be updated when the request arrives
	 *
	 */

	Set_request_timer((NODE_COUNT + NODE_ID) * REQUEST_TIME_SLOT);
	//Set_answer_timer(REQUEST_TIME_SLOT);

	/*Interrupt with no-reset on MR0*/
	HAL_WRITE_UINT32(TIMER1_MCR, 0x1);

	/* Enable Timer 1 and start counting */
	HAL_WRITE_UINT32(TIMER1_TCR, 0x01);

}

cyg_uint32 Timer1_isr(cyg_vector_t vector, cyg_addrword_t data)
{
	cyg_uint32 old_MCR_reg;
	cyg_uint32 old_IR_reg;

	cyg_uint32 curr_time;

	cyg_interrupt_mask(vector);
	cyg_interrupt_acknowledge(vector);

	/* get the current time*/
	HAL_READ_UINT32(TIMER1_TC, curr_time);

	/* read the old match register and the interrupt register */
	HAL_READ_UINT32(TIMER1_MCR, old_MCR_reg);
	HAL_READ_UINT32(TIMER1_IR, old_IR_reg);

	/*
	 * read which interrupt occurred
	 * and save it to a global variable to handle it from dsr
	 */
	HAL_READ_UINT32(TIMER1_IR, InterruptBit);

	//diag_printf("Timer1_isr : %u  %x  %x \r\n", curr_time, old_MCR_reg,			old_IR_reg);

	 HAL_READ_UINT32(TIMER1_IR, InterruptBit);

	        switch (InterruptBit) {
	        case 1: // request timer - macrotick
	                HAL_WRITE_UINT32(TIMER1_IR, 1);
	                old_MCR_reg = (old_MCR_reg & ~0x01);
	                HAL_WRITE_UINT32(TIMER1_MCR, old_MCR_reg);
	                break;
	        case 2: //wait - microtick
	                HAL_WRITE_UINT32(TIMER1_IR, 2);
	                old_MCR_reg = (old_MCR_reg & ~0x08);
	                HAL_WRITE_UINT32(TIMER1_MCR, old_MCR_reg);
	                break;

	        default:
	                HAL_WRITE_UINT32(TIMER1_IR, 3);
	                old_MCR_reg = (old_MCR_reg & ~0x09);
	                HAL_WRITE_UINT32(TIMER1_MCR, old_MCR_reg);

	                break;
	        }

	        return (CYG_ISR_CALL_DSR);

	HAL_READ_UINT32(TIMER1_MCR, old_MCR_reg);
	HAL_READ_UINT32(TIMER1_IR, old_IR_reg);
	diag_printf("Timer1_isr2 : %x  %x \r\n\r\n\r\n", old_MCR_reg, old_IR_reg);

	return (CYG_ISR_CALL_DSR);

}
void Timer1_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
	//diag_printf("Timer1_dsr : %x   \r\n\r\n\r\n", InterruptBit);


	   switch (InterruptBit) {
	        // schedule next request; N*macroticks
	        // void radio_request(cyg_addrword_t index)
	        case 1:
	        	cyg_flag_setbits(&Timed_clock_sync_event,
	        		TIMED_CLOCK_SYNC_REQUEST_EVENT);
	                break;
	                // schedule next answer - microtick
	        case 2:
	        	cyg_flag_setbits(&Timed_clock_sync_event, TIMED_CLOCK_SYNC_ANSWER_EVENT);
	                break;

	        default:
	        	cyg_flag_setbits(&Timed_clock_sync_event,
	        		        	 				TIMED_CLOCK_SYNC_REQUEST_EVENT);
	        	cyg_flag_setbits(&Timed_clock_sync_event, TIMED_CLOCK_SYNC_ANSWER_EVENT);
	                break;
	        }

	        cyg_interrupt_unmask(vector);

}
/****************************************************************************/
/** 																	   **/
/** 							LOCAL FUNCTIONS 						   **/
/** 																	   **/
/****************************************************************************/

/****************************************************************************/
/** 																	   **/
/** 							EOF 							   		   **/
/** 																	   **/
/****************************************************************************/
